﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using HA.ModFlow.Domain.DomainLayer;

using HA.MT3DMS.FileLayer;

namespace HA.MT3DMS.DomainLayer
{
    [Serializable]
    public class SourceSinkMixing : MTPackage,ICloneable
    {

        public SourceSinkMixing()
        {

            this._spMixings = new List<MixingItem>();

            this._currentSpecies = new List<string>();

            this._isUsePrecious = new List<bool>();



        }





        List<MixingItem> _spMixings;

        public List<MixingItem> SpMixings
        {
            get { return _spMixings; }

        }

        List<List<SPPolygonConc>> _rechargeSpConc = new List<List<SPPolygonConc>>();

        public List<List<SPPolygonConc>> RechargeSpConc
        {
            get { return _rechargeSpConc; }
          
        }




        List<List<SPPolygonConc>> _evtSpConc = new List<List<SPPolygonConc>>();

        public List<List<SPPolygonConc>> EvtSpConc
        {
            get { return _evtSpConc; }
          
        }




        public void GetRechAndEvt(List<List<SPPolygonConc>> rech, List<List<SPPolygonConc>> evt)
        {
            this._rechargeSpConc = rech;
            this._evtSpConc = evt;
        }
      



        int _nPeriods;

        public int NPeriods
        {
            get { return _nPeriods; }

        }

        int _nSpecies;

        public int NSpecies
        {
            get { return _nSpecies; }

        }
        protected List<bool> _isUsePrecious = new List<bool>();

        public List<bool> IsUsePrecious
        {
            get { return _isUsePrecious; }
            set { _isUsePrecious = value; }
        }


        List<string> _currentSpecies;

        public List<string> CurrentSpecies
        {
            get { return _currentSpecies; }

        }


        public int MaxSS
        {
            get {

                int nTotal = 0;

                if (this._mfData.SourceSinks.Wells.Enabled)
                {
                    

                    nTotal += this._mfData.SourceSinks.Wells.InnerList.Count;

                }

                if (this._mfData.SourceSinks.Rivers.Enabled)
                {
                   

                    nTotal += this._mfData.SourceSinks.Rivers.InnerList.Count;

                }


                if (this._mfData.SourceSinks.Drains.Enabled)
                {


                    nTotal += this._mfData.SourceSinks.Drains.InnerList.Count;

                }

                if (this._mfData.SourceSinks.GeneralHeads.Enabled)
                {
                   

                    nTotal += this._mfData.SourceSinks.GeneralHeads.InnerList.Count;

                }


                if (this._mfData.SourceSinks.SpecifiedHeads.Enabled)
                {
                    nTotal += this._mfData.SourceSinks.SpecifiedHeads.InnerList.Count;
                    
                }

              

                ///取得constant cell的个数
                ///

                nTotal += this._mfData.GridData.WaterGrid.GetConstantCellCount();

                return nTotal;


            }


        }

      

        public bool IsUseEvt
        {
            get {

                if (this._mfData.SourceSinks.Evts.Enabled)
                {
                    return true;


                }
                else
                {
                    return false;
                }
            }
        }


        public bool IsUseRecharge
        {
            get
            {

                if (this._mfData.SourceSinks.Recharges.Enabled)
                {
                    return true;


                }
                else
                {
                    return false;
                }
            }
        }



        public void ResetMixingItems(List<MixingItem> miList, List<bool> usePre)
        {


            this._spMixings.Clear();
            this._spMixings.AddRange(miList);

            this._isUsePrecious.Clear();

            this._isUsePrecious.AddRange(usePre);





        }


        /// <summary>
        /// 
        /// 清空选定类型的条目
        /// </summary>
        /// <param name="type"></param>
        public void ClearMixingItems(MixingSSType type)
        {
            List<MixingItem> lst = new List<MixingItem>();

            foreach (MT3DMS.DomainLayer.MixingItem item in this.SpMixings)
            {
                if (item.SsType == type)
                {
                    lst.Add(item);

                }

            }

            foreach (MixingItem item in lst)
            {
                this.SpMixings.Remove(item);
                

            }
                            
 
        }


        public void ResetModflow(ModFlowData mf)
        {

            this._mfData = mf;


 
        }


        ModFlowData _mfData;


    


        public void OnStressPeriodReset(int nPeriods)
        {
            this._nPeriods = nPeriods;

            this._isUsePrecious.Clear();

            for (int i = 0; i < nPeriods; i++)
            {
                //this._isUsePrecious[i] = false;
                this._isUsePrecious.Add(false);
            }

            foreach (MixingItem item in this._spMixings)
            {
                item.OnStressPeriodReset(nPeriods);

            }



            foreach (List<SPPolygonConc> item in this._evtSpConc)
            {
                item.Clear();

                for (int j = 0; j < this._nPeriods; j++)
                {
                    SPPolygonConc sp = new SPPolygonConc(this._nrow,this._ncol);

                    item.Add(sp);
                    
                }

                
            }


            foreach (List<SPPolygonConc> item in this._rechargeSpConc)
            {
                item.Clear();

                for (int j = 0; j < this._nPeriods; j++)
                {
                    SPPolygonConc sp = new SPPolygonConc(this._nrow, this._ncol);

                    item.Add(sp);

                }


            }


        }

        public void OnGridReset(int nrows, int ncols, int nlayers)
        {

            this._nlayer = nlayers;
            this._ncol = ncols;

            this._nrow = nrows;


            foreach (List<SPPolygonConc> item in this._evtSpConc)
            {

                foreach (SPPolygonConc sp in item)
                {
                    sp.OnResetGrid(this._nrow,this._ncol);
                    
                }

              


            }

            foreach (List<SPPolygonConc> item in this._rechargeSpConc)
            {

                foreach (SPPolygonConc sp in item)
                {
                    sp.OnResetGrid(this._nrow, this._ncol);

                }




            }





        }

        int _nlayer;
        int _nrow;
        int _ncol;

        public object Clone()
        {
            SourceSinkMixing obj = new SourceSinkMixing();
            //obj = (SourceSinkMixing)this.MemberwiseClone();
            for (int i = 0; i < this._spMixings.Count; i++)
            {
                obj._spMixings.Add((MixingItem)this._spMixings[i].Clone());
            }
            obj.RechargeSpConc.Clear();
            for (int i = 0; i < this._rechargeSpConc.Count; i++)
            {
                List<SPPolygonConc> arrycon = new List<SPPolygonConc>();
                SPPolygonConc con = new SPPolygonConc();
                for (int j = 0; j < this._rechargeSpConc[i].Count; j++)
                {
                    con = (SPPolygonConc)this._rechargeSpConc[i][j].Clone();
                    arrycon.Add(con);
                }
                obj._rechargeSpConc.Add(arrycon);
            }
            obj._evtSpConc.Clear();
            for (int i = 0; i < this._evtSpConc.Count; i++)
            {
                List<SPPolygonConc> arrycon = new List<SPPolygonConc>();
                SPPolygonConc con = new SPPolygonConc();
                for (int j = 0; j < this._evtSpConc[i].Count; j++)
                {
                    con = (SPPolygonConc)this._evtSpConc[i][j].Clone();
                    arrycon.Add(con);
                }
                obj._evtSpConc.Add(arrycon);
            }
            obj._isUsePrecious.Clear();
            for (int i = 0; i < this._isUsePrecious.Count; i++)
            {
                obj._isUsePrecious.Add(this._isUsePrecious[i]);
            }
            obj._currentSpecies.Clear();
            for (int i = 0; i < this._currentSpecies.Count; i++)
            {
                obj._currentSpecies.Add(this._currentSpecies[i]);
            }
            obj._nPeriods = this._nPeriods;
            obj._nSpecies = this._nSpecies;

            obj._nlayer = this._nlayer;           
            obj._nrow=this ._nlayer ;
            obj._ncol=this ._ncol ;
            obj._mfData = this._mfData;
            return obj;
        }
        public MixingItem BuildNewMixingItem()
        {
            MixingItem mi = new MixingItem(1, 1, 1, MixingSSType.CONHEAD, this._nPeriods, this._currentSpecies);

            return mi;


        }


        public void OnSpeciesReset(List<string> spNames)
        {

            this._nSpecies = spNames.Count;
            this._currentSpecies = spNames;

            foreach (MixingItem item in this._spMixings)
            {
                item.OnSpeciesReset(spNames);

            }


            this._rechargeSpConc.Clear();

            this._evtSpConc.Clear();



            for (int i = 0; i < this._nSpecies; i++)
            {
                List<SPPolygonConc> conc=new List<SPPolygonConc> ();

                List<SPPolygonConc> concEVT = new List<SPPolygonConc>();



                for (int j = 0; j < this._nPeriods; j++)
                {
                    SPPolygonConc sp = new SPPolygonConc(this._nrow,this._ncol);

                    conc.Add(sp);

                    concEVT.Add((SPPolygonConc)sp.Clone());

                    
                    
                }


                this._rechargeSpConc.Add(conc);

                this._evtSpConc.Add(concEVT);
                
            }


        }


        public SSMixingPack ToPack()
        {
            SSMixingPack pack = new SSMixingPack();

           
           

            if (this._mfData.SourceSinks.Wells.Enabled)
            {
                pack.FWEL = "T";

             
                
            }

            if (this._mfData.SourceSinks.Rivers.Enabled)
            {
                pack.FRIV = "T";

             

            }

            if (this._mfData.SourceSinks.Drains.Enabled)
            {
                pack.FDRN = "T";

              

            }

            if (this._mfData.SourceSinks.GeneralHeads.Enabled)
            {
                pack.FGHB = "T";
 

            }

            if (this._mfData.SourceSinks.Recharges.Enabled)
            {
                pack.FRCH = "T";

            }

            if (this._mfData.SourceSinks.Evts.Enabled)
            {
                pack.FEVT = "T";

            }
          
            
            ///取得constant cell的个数
            ///



            pack.MXSS = this.MaxSS;






  
            //这个字段的设计是错误的，需要逐应力期输入，分别表示两个面妆源汇的浓度输入


            for (int i = 0; i < this.NSpecies; i++)
            {
                List<double[,]> rechar = new List<double[,]>();
                List<double[,]> evt = new List<double[,]>();
                for (int j = 0; j < this.NPeriods; j++)
                {
                    rechar.Add(this.RechargeSpConc[i][j].Conc);
                    evt.Add(this.EvtSpConc[i][j].Conc);
                }
               
                pack.CRCH.Add(rechar);
                pack.CEVT.Add(evt);
            }

           
            for (int i = 0; i < this.NPeriods; i++)
            {
                if (this.RechargeSpConc.Count > 0)
                {
                    if (this.RechargeSpConc[0][i].UsePrecious)
                    {
                        pack.INCRCH.Add(-1);
                    }
                    else
                    {
                        pack.INCRCH.Add(0); //当使用上一应力期时 INCRCH为-1,反之为0,跟应力期有关
                    }                    
                }
                if (this.EvtSpConc.Count > 0)
                {
                    if (this.EvtSpConc[0][i].UsePrecious)
                    {
                        pack.INCEVT.Add(-1);
                    }
                    else
                    {
                        pack.INCEVT.Add(0); //当使用上一应力期时 INCRCH为-1,反之为0,跟应力期有关
                    }  
                }       
            }
  
            pack.NSS = this._spMixings.Count;
           for (int j=0;j<this .NPeriods;j++)
           {
               List<PointConcentration> arry = new List<PointConcentration>();
               for (int i = 0; i < this.SpMixings.Count; i++)
               {
                   PointConcentration pc = new PointConcentration();
                   pc.KSS = this.SpMixings[i].Layer;
                   pc.ISS = this.SpMixings[i].Row;
                   pc.JSS = this.SpMixings[i].Col;


                   switch (this.SpMixings[i].SsType)
                   {
                       case MixingSSType.WELL:
                           pc.ITYPE = 2;
                           break;
                       case MixingSSType.CONHEAD:
                           pc.ITYPE = 1;
                           break;
                       case MixingSSType.RIVER:
                           pc.ITYPE = 4;
                           break;
                       case MixingSSType.GENHEAD:
                           pc.ITYPE = 5;
                           break;
                       case MixingSSType.SECCONC:
                           pc.ITYPE = -1;
                           break;
                       case MixingSSType.MASSLOAD:
                           pc.ITYPE = 15;
                           break;
                       default:
                           break;
                   }
               

                   ///这里的写法只是一个临时测试的写法，因为还没有完全考虑清楚其中结构
                   int n = 0;
                   foreach (List<double> item in this.SpMixings[i].SpDic.Values)
                   {
                       ///只写首个css值
                       if (n == 0)
                       {
                           pc.CSS = item[j];
                       }
                       pc.CSSMS.Add(item[j]);
                       n++;
                   }
                   arry.Add(pc);
               }
               pack.PointConcentration.Add(arry);

                //pack.PointConcentration.Add(pc);
            }


           for (int i = 1; i < this.IsUsePrecious.Count; i++)
           {
               if (this.IsUsePrecious[i])
               {
                   pack.PointConcentration[i] = pack.PointConcentration[i - 1];
                   //for (int j = 0; j < pack.PointConcentration[i-1].Count; j++)
                   //{
                   //    pack.PointConcentration[i][j].CSS = pack.PointConcentration[i - 1][j].CSS;
                   //    pack.PointConcentration[i][j].CSSMS = pack.PointConcentration[i - 1][j].CSSMS;
                   //    pack.PointConcentration[i][j].ISS = pack.PointConcentration[i - 1][j].ISS;
                   //    pack.PointConcentration[i][j].ITYPE = pack.PointConcentration[i - 1][j].ITYPE;
                   //    pack.PointConcentration[i][j].JSS = pack.PointConcentration[i - 1][j].JSS;
                   //    pack.PointConcentration[i][j].KSS = pack.PointConcentration[i - 1][j].KSS;
                   //}

               }
           }


            return pack;
        }
    }
}
